package com.yanqu.road.entity.activity.chefduel;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.entity.DataObject;

import java.math.BigInteger;
import java.util.*;

//阶段1成品食材比赛
public class ChefDuelMatch extends DataObject{

	private int rankNum = 1000;

	private int activityId;

	private int no;//比赛场次

	private String tableData;//菜桌信息

	private Map<Integer, ChefDuelMatchDish> cookBoyMatchDishMap;

	private long openTime;

	private long overTime;//结束时间，时间到了结束，参赛作品满了结束，每天时间到了结束

	private LinkedList<ChefDuelMatchRank> matchRankList = new LinkedList<>();

	private UserRankSort userRankSort = new UserRankSort();

	private LinkedList<ChefDuelDishRank> dishRankList = new LinkedList<>();

	private DishRankSort dishRankSort = new DishRankSort();

	public int getActivityId() {
		return activityId;
	}

	public void setActivityId(int activityId) {
		this.activityId = activityId;
	}

	public int getNo() {
		return no;
	}

	public void setNo(int no) {
		this.no = no;
	}

	public String getTableData() {
		return tableData;
	}

	public void setTableData(String tableData) {
		if(!tableData.equals(this.tableData)){
			this.tableData = tableData;
			setUpdateOption();
		}
	}

	public long getOpenTime() {
		return openTime;
	}

	public void setOpenTime(long openTime) {
		if(openTime != this.openTime){
			this.openTime = openTime;
			setUpdateOption();
		}
	}

	public long getOverTime() {
		return overTime;
	}

	public void setOverTime(long overTime) {
		if(overTime != this.overTime){
			this.overTime = overTime;
			setUpdateOption();
		}
	}


	public Map<Integer, ChefDuelMatchDish> getMatchFoodMap(){
		if(this.cookBoyMatchDishMap == null){
			this.cookBoyMatchDishMap = JSON.parseObject(tableData, new TypeReference<Map<Integer, ChefDuelMatchDish>>() {});
		}
		return this.cookBoyMatchDishMap;
	}

	public void setMatchFoodMap(Map<Integer, ChefDuelMatchDish> cookBoyMatchFoodMap){
		this.cookBoyMatchDishMap = cookBoyMatchFoodMap;
		setTableData(JSON.toJSONString(cookBoyMatchFoodMap));
	}

	public LinkedList<ChefDuelMatchRank> getMatchRankList(){
		return matchRankList;
	}


	public ChefDuelMatchRank getTopUserRank(){
		if(matchRankList.size() > 0){
			return matchRankList.get(0);
		}
		return null;
	}

	public int getDishRank(long userId,int id){
		int rank = 1;
		for(ChefDuelDishRank cookBoyDishRank : dishRankList){
			if(cookBoyDishRank.getUserId() == userId && cookBoyDishRank.getMatchDish().getId() == id){
				return rank;
			}
			rank++;
		}
		return -1;
	}


	public void rankInit(){
		if(cookBoyMatchDishMap == null){
			this.cookBoyMatchDishMap = JSON.parseObject(tableData, new TypeReference<Map<Integer, ChefDuelMatchDish>>() {});
		}
		List<Long> initUser = new ArrayList<>();
		for(ChefDuelMatchDish cookBoyMatchDish: cookBoyMatchDishMap.values()){
			if(!initUser.contains(cookBoyMatchDish.getUserId())){
				matchRankChange(cookBoyMatchDish.getUserId());
				initUser.add(cookBoyMatchDish.getUserId());
			}
			dishRankChange(cookBoyMatchDish);
		}
	}

	public void rankChange(ChefDuelMatchDish cookBoyMatchDish){
		matchRankChange(cookBoyMatchDish.getUserId());
		dishRankChange(cookBoyMatchDish);
	}

	public BigInteger getAllDishFraction(long userId){
		BigInteger value = BigInteger.ZERO;
		Map<Integer, ChefDuelMatchDish> cookBoyMatchDishMap = getMatchFoodMap();
		for(ChefDuelMatchDish cookBoyMatchDish : cookBoyMatchDishMap.values()){
			if(cookBoyMatchDish.getUserId() == userId){
				value = value.add(BigInteger.valueOf(cookBoyMatchDish.getFraction()));
			}
		}
		return value;
	}

	public ChefDuelMatchDish getTopDishInfo(long userId){
		ChefDuelMatchDish res = null;
		Map<Integer, ChefDuelMatchDish> cookBoyMatchDishMap = getMatchFoodMap();
		for(ChefDuelMatchDish cookBoyMatchDish : cookBoyMatchDishMap.values()){
			if(cookBoyMatchDish.getUserId() == userId){
				if(res == null){
					res = cookBoyMatchDish;
				}else{
					if(cookBoyMatchDish.getFraction() > res.getFraction() || (cookBoyMatchDish.getFraction() == res.getFraction() && cookBoyMatchDish.getTime() < res.getTime())){
						res = cookBoyMatchDish;
					}
				}
			}
		}
		return res;
	}

	public ChefDuelMatchRank initMatchRank(long userId) {
		ChefDuelMatchRank rank = new ChefDuelMatchRank();
		return updateMatchRank(rank,userId);
	}
	private ChefDuelMatchRank replaceLastMatchRank(long userId) {
		ChefDuelMatchRank last = matchRankList.getLast();
		return updateMatchRank(last,userId);
	}

	public ChefDuelMatchRank updateMatchRank(ChefDuelMatchRank cookBoyMatchRank, long userId) {
		long serverId = 0;
		long foodCookTime = 0;
		BigInteger value = BigInteger.ZERO;
		List<ChefDuelMatchDish> matchFoodList = new ArrayList<>();
		Map<Integer, ChefDuelMatchDish> cookBoyMatchDishMap = getMatchFoodMap();
		for(ChefDuelMatchDish cookBoyMatchDish : cookBoyMatchDishMap.values()){
			if(cookBoyMatchDish.getUserId() == userId){
				serverId = cookBoyMatchDish.getServerId();
				matchFoodList.add(cookBoyMatchDish);
				BigInteger newOne = BigInteger.valueOf(cookBoyMatchDish.getFraction());
				if(newOne.compareTo(value) > 0 || (newOne.compareTo(value) == 0 && cookBoyMatchDish.getTime() < foodCookTime)){
					value = BigInteger.valueOf(cookBoyMatchDish.getFraction());
					foodCookTime = cookBoyMatchDish.getTime();
				}
			}
		}
		cookBoyMatchRank.setServerId(serverId);
		cookBoyMatchRank.setUserId(userId);
		cookBoyMatchRank.setValue(value);
		cookBoyMatchRank.setFoodCookTime(foodCookTime);
		cookBoyMatchRank.setMatchDishList(matchFoodList);
		cookBoyMatchRank.dishSort();
		cookBoyMatchRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
		return cookBoyMatchRank;
	}

	public void matchRankChange(long userId) {
		ChefDuelMatchRank cookBoyMatchRank = null;
		synchronized (this) {
            int size = matchRankList.size();
            if (!matchRankList.stream().anyMatch(predicate -> predicate.getUserId() == userId)) {
				ChefDuelMatchDish cookBoyMatchDish = getTopDishInfo(userId);
                if (size < rankNum) {
					cookBoyMatchRank= initMatchRank(userId);
					matchRankList.add(cookBoyMatchRank);
                } else if (matchRankList.getLast().getValue().compareTo(getAllDishFraction(userId)) < 0 ||
						(matchRankList.getLast().getValue().compareTo(BigInteger.valueOf(cookBoyMatchDish.getFraction())) == 0 && matchRankList.getLast().getFoodCookTime() > cookBoyMatchDish.getTime())) {
					cookBoyMatchRank = replaceLastMatchRank(userId);
                }
            } else {
                for (ChefDuelMatchRank tempRank : matchRankList) {
                    if (tempRank.getUserId() == userId) {
						updateMatchRank(tempRank,userId);
                        break;
                    }
                }
            }
			matchRankList.sort(userRankSort);
		}
    }

	public ChefDuelDishRank initDishRank(ChefDuelMatchDish cookBoyMatchDish) {
		ChefDuelDishRank rank = new ChefDuelDishRank();
		return updateDishRank(rank,cookBoyMatchDish);
	}

	private ChefDuelDishRank replaceLastDishRank(ChefDuelMatchDish cookBoyMatchDish) {
		ChefDuelDishRank last = dishRankList.getLast();
		return updateDishRank(last,cookBoyMatchDish);
	}

	public ChefDuelDishRank updateDishRank(ChefDuelDishRank cookBoyDishRank, ChefDuelMatchDish cookBoyMatchDish) {
		cookBoyDishRank.setUserId(cookBoyMatchDish.getUserId());
		cookBoyDishRank.setValue(BigInteger.valueOf(cookBoyMatchDish.getFraction()));
		cookBoyDishRank.setMatchDish(cookBoyMatchDish);
		cookBoyDishRank.setLastUpdateTime(System.currentTimeMillis() / 1000);
		return cookBoyDishRank;
	}

	public void dishRankChange(ChefDuelMatchDish cookBoyMatchDish) {
		ChefDuelDishRank cookBoyDishRank = null;
		synchronized (this) {
            int size = dishRankList.size();
            if (!dishRankList.stream().anyMatch(predicate -> predicate.getMatchDish().getPos() == cookBoyMatchDish.getPos())) {
                if (size < rankNum) {
					cookBoyDishRank= initDishRank(cookBoyMatchDish);
					dishRankList.add(cookBoyDishRank);
                } else if (dishRankList.getLast().getValue().compareTo(BigInteger.valueOf(cookBoyMatchDish.getFraction())) < 0) {
					cookBoyDishRank = replaceLastDishRank(cookBoyMatchDish);
                }
            } else {
                for (ChefDuelDishRank tempRank : dishRankList) {
                    if (tempRank.getMatchDish().getPos() == cookBoyMatchDish.getPos()) {
						updateDishRank(tempRank,cookBoyMatchDish);
                        break;
                    }
                }
            }
			dishRankList.sort(dishRankSort);
		}
    }



	//从大到小
	static class UserRankSort implements Comparator<ChefDuelMatchRank> {
		@Override
		public int compare(ChefDuelMatchRank o1, ChefDuelMatchRank o2) {
			if (o1.getValue().compareTo(o2.getValue()) == 0) {
				return 0;
			}
			if (o1.getValue().compareTo(o2.getValue()) <= 0) {
				return 1;
			}
			return -1;
		}
	}

	//从大到小
	static class DishRankSort implements Comparator<ChefDuelDishRank> {
		@Override
		public int compare(ChefDuelDishRank o1, ChefDuelDishRank o2) {
			if (o1.getValue().compareTo(o2.getValue()) == 0) {
				return 0;
			}
			if (o1.getValue().compareTo(o2.getValue()) <= 0) {
				return 1;
			}
			return -1;
		}
	}
}
